package pl;

import javacard.framework.Util;

public class Utils {

	/* static methods */

	public static short byteArrayToShort(byte[] array) {
		return (short) (((array[0] & 0xFF) << 8) | (array[1] & 0xFF));
	}

	public static byte[] shortOnByteArray(short value) {
		return new byte[] { (byte) (value & (short) 0x00FF),
				(byte) ((value & (short) 0xFF00) >> 8) };
	}
	
	public static short shortOnByteArray(short value, byte[] out, short outOff) {
		
		byte p1 = (byte) (value & (short) 0x00FF);
		byte p2 = (byte) ((value & (short) 0xFF00) >> 8);
		
		out[outOff] = p2;
		outOff++;
		out[outOff] = p1;
		
		return 2;
	}

	public static void ClearArray(byte[] array) {
		for (short i = 0; i < (short) array.length; i++) {
			array[i] = (byte) 0x00;
		}
	}

	public static void ClearArray(byte[] array, short len) {
		for (short i = 0; i < len; i++) {
			array[i] = (byte) 0x00;
		}
	}

	public static void XorTwoArrays(byte[] a1, byte[] a2, short aLen,
			byte[] result) {
		for (short i = 0; i < aLen; i++) {
			result[i] = (byte) (a1[i] ^ a2[i]);
		}
	}

	public static void increment(byte[] array, short aLen) {
		short i;
		for (i = 0; i <= (short) (aLen - 1); i++) {
			array[i]++;
			if (array[i] != 0)
				break;
		}
	}

	static short getLength(byte[] berTLVArray, short bOff) {
		if (berTLVArray == null)
			throw new NullPointerException();

		// length //9F 66 81 00 =?
		short checkBit = (short) (berTLVArray[bOff] & 0x80);
		
		if (checkBit == 0x00) {
			// return (short) berTLVArray[(byte) (bOff)];
			return (short) berTLVArray[bOff];
		} else {
			checkBit = (short) (berTLVArray[bOff] & 0x03);
			bOff++;
			switch (checkBit) {
			case 1:
				// 81 81
				if ((berTLVArray[(short) bOff] & 0x80) == 0x80)
					return (short) (berTLVArray[(short) (bOff)] & 0x00FF);
				else
					throw new NullPointerException();

			case 2:
				return Util.makeShort(berTLVArray[(short) (bOff)],
						berTLVArray[(short) (bOff + 1)]);
			default:
				throw new NullPointerException();
			}
		}

	}

	static short getSizeBytesLen(byte[] berTLVArray, short bOff) {
		if (berTLVArray == null)
			throw new NullPointerException();

		short checkBit = (short) (berTLVArray[bOff] & 0x80);

		if (checkBit == 0x00) {
			return 1;
		} else {
			checkBit = (short) (berTLVArray[bOff] & 0x03);
			bOff++;
			switch (checkBit) {
			case 1:
				return 2;

			case 2:
				bOff++;
				return 3;
			default:
				throw new NullPointerException();
			}
		}
	}

	static short buildTlvLength(short length, byte[] output, short offset) {

		if (length < 128) {
			output[(short) offset] = (byte) length;
			return 1;
		} else if (length > 127 && length < 256) {
			/*
			 * output[(short)offset] = (byte)length; output[(short)(offset + 1)]
			 * = (byte)0x81;
			 */

			output[(short) (offset + 1)] = (byte) length;
			output[(short) offset] = (byte) 0x81;
			return 2;
		} else if (length > 255) {
			/* short on bytes */
			/*
			 * output[(short)(offset)] = (byte) (length & (short) 0x00FF);
			 * output[(short)(offset + 1)] = (byte) ((length & (short) 0xFF00)
			 * >> 8); output[(short)(offset + 2)] = (byte) 0x82;
			 */

			output[(short) (offset + 2)] = (byte) (length & (short) 0x00FF);
			output[(short) (offset + 1)] = (byte) ((length & (short) 0xFF00) >> 8);
			output[(short) (offset)] = (byte) 0x82;

			return 3;
		}
		return 0;

	}

	static short findFirstOccurenceOfTagByte(byte[] array, short offset,
			short len, byte tag) {
		
		for (short i = offset; i < (short)(len + offset); i++) {
			if ((byte)array[i] == (byte)tag)
				return i;
		}

		return -1;
	}
}
